package com.open.common.model;

import com.open.common.utils.CollectionUtils;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;

/**
 * @author dashu
 * @date 2025/1/2 18:29
 * @description 分页参数
 */
@XmlType(name = "Page")
@XmlAccessorType(XmlAccessType.FIELD)
public class Page<T> implements Serializable {
    private static final long serialVersionUID = 3496103014062037454L;

    /**
     * 是否有下一页
     **/
    private boolean hasNext;

    /**
     * 是否有上一页
     **/
    private boolean hasPre;

    /**
     * 当前页包含的记录列表
     **/
    private List<T> items;

    /**
     * 当前页页码
     **/
    private int index = 1;

    /**
     * 每页包含的记录数
     **/
    private int size = 15;

    /**
     * 总页数
     **/
    private int totalPage;

    /**
     * 总条数
     **/
    private int total;

    /**
     * 逻辑分页处理
     *
     * @param list 原始数据列表
     * @param page 分页参数对象
     * @param <T>  数据类型
     * @return 分页后的数据列表
     */
    public static <T> List<T> startPage(List<T> list, Page<T> page) {
        // 空列表处理
        if (CollectionUtils.isEmpty(list)) {
            page.setItems(Collections.emptyList());
            page.setTotal(0);
            return Collections.emptyList();
        }

        // 参数校验和修正
        if (page.getIndex() < 1) {
            page.setIndex(1);
        }
        if (page.getSize() < 1) {
            page.setSize(15); // 使用默认大小
        }

        // 计算总记录数和总页数
        int total = list.size();
        page.setTotal(total);

        // 计算起始和结束位置
        int startPoint = (page.getIndex() - 1) * page.getSize();
        int endPoint = Math.min(startPoint + page.getSize(), total);

        // 边界检查
        if (startPoint >= total) {
            // 当前页超出范围，返回空列表
            page.setItems(Collections.emptyList());
            return Collections.emptyList();
        }

        // 截取分页数据
        List<T> pagedList = list.subList(startPoint, endPoint);
        page.setItems(pagedList);

        return pagedList;
    }

    public int getIndex() {
        return this.index;
    }

    public void setIndex(int index) {
        this.index = index;
    }

    public boolean isHasPre() {
        return this.hasPre;
    }

    public void setHasPre(boolean hasPre) {
        this.hasPre = hasPre;
    }

    public boolean isHasNext() {
        return this.hasNext;
    }

    public void setHasNext(boolean hasNext) {
        this.hasNext = hasNext;
    }

    public List<T> getItems() {
        return this.items == null ? Collections.<T>emptyList() : this.items;
    }

    public void setItems(List<T> items) {
        this.items = items;
    }

    public int getTotal() {
        return total;
    }

    public void setTotal(int total) {
        this.total = total;
        this.setTotalPage(total % size == 0 ? total / size : total / size + 1);
        this.setHasPre(this.index > 1);
        this.setHasNext(this.index < this.totalPage);
    }

    public int getTotalPage() {
        return totalPage;
    }

    public void setTotalPage(int totalPage) {
        this.totalPage = totalPage;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public Page(int index, int size) {
        super();
        this.index = index;
        this.size = size;
    }

    public Page() {
        super();
    }

    @Override
    public String toString() {
        return "Page{" +
                "hasNext=" + hasNext +
                ", hasPre=" + hasPre +
                ", items=" + items +
                ", index=" + index +
                ", size=" + size +
                ", totalPage=" + totalPage +
                ", total=" + total +
                '}';
    }
}